package org.easy4j.framework.core.orm;


/**
 * @author: liuyong
 * @since 1.0
 */
public class SQLBuilder {

    public static String getSelectColumns(Class entityClass) {

        Mapping mapping = EntityMapping.getMapping(entityClass);
        StringBuilder colBuilder = new StringBuilder();

        for(String column : mapping.getColumns()) {
            colBuilder.append(column).append(",") ;
        }

        colBuilder.deleteCharAt(colBuilder.length() - 1) ;
        return  colBuilder.toString() ;

    }

    public static String generateSelectSQL(String columns ,String tableName ,String conditions){
        if(columns == null || columns.length() == 0) {
            return join("select * from",tableName ,conditions);
        }

        return join("select",columns ,"from" ,tableName ,conditions);
    }


    public static String generateSelectCountSQL(String tableName ,String conditions){
        return join("select count(1) from" ,tableName ,conditions);
    }

    public static String generateSelectSqlForPager(String columns ,String tableName ,String conditions ,int pageNumber,int pageSize ){

        int start = 0 ;

        if(pageNumber > 1)
            start = (pageNumber - 1) * pageSize ;

        StringBuilder limitBuilder = new StringBuilder(5);
        limitBuilder.append("limit ").append(start).append(',').append(pageSize);

        if(columns == null || columns.length() == 0) {
            return join("select * from",tableName,conditions,limitBuilder.toString());
        }
        return join("select",columns,"from",tableName,conditions,limitBuilder.toString());
    }


    public static String generateUpdateSql(Class entityClass) {

        String tableName    = EntityMapping.getTableName(entityClass);
        Mapping mapping     = EntityMapping.getMapping(tableName);

        String[] columns = mapping.getColumns() ;

        StringBuilder sets  = new StringBuilder();
        String IdColumn     = columns[Mapping.ID_INDEX]  ;
        for( int i = 0 ; i < columns.length ; i++ ) {

            String column =  columns[i] ;

           /* if(Mapping.ID_INDEX == i)
                continue;*/

            if(!mapping.updatableBitSet.get(i))
                continue;

            sets.append(column).append(" =?,");
        }

        sets.deleteCharAt(sets.length() - 1);
        return join("update",tableName ,"set" ,sets.toString() ,"where" ,IdColumn,"=?") ;
    }

    public static String generateUpdateSQL(String tableName,String sets ,String conditions){

        int len = sets.length();
        int index = 0 ;
        for(; index < len ; ){
            char c = sets.charAt(index);
            if(c == ' '){
                index++ ;
            }
            break;
        }

        String setStr = sets.substring(index , index + 4);

        if(setStr.equalsIgnoreCase("set "))
            return join("update",tableName,sets ,conditions) ;
        return  join("update",tableName,"set",sets ,conditions) ;
    }

    public static String generateInsertSQL(String tableName,Mapping mapping){

        String[] columns = mapping.getColumns() ;

        StringBuilder sql = new StringBuilder("INSERT INTO ");
        sql.append(tableName).append('(');
        StringBuilder placeHolder = new StringBuilder();

        for(int i = 0 ; i < columns.length ; i++ ) {
            if( !mapping.insertableBitSet.get(i) )
                continue;
            sql.append(columns[i]).append(',');
            placeHolder.append('?').append(',') ;
        }

        sql.deleteCharAt(sql.length() - 1);
        placeHolder.deleteCharAt(placeHolder.length() - 1);

        sql.append(") VALUES(");
        placeHolder.append(')');

        sql.append(placeHolder);

        return sql.toString() ;

    }

    public static String generateInsertSQL(String tableName,String ... columns ){
        StringBuilder sql = new StringBuilder("INSERT INTO ");
        sql.append(tableName).append('(');
        StringBuilder placeHolder = new StringBuilder();

        for(int i = 0 ; i < columns.length ; i++ ) {
            if(columns[i].equals("id"))
                continue;
            sql.append(columns[i]).append(',');
            placeHolder.append('?').append(',') ;
        }

        sql.deleteCharAt(sql.length() - 1);
        placeHolder.deleteCharAt(placeHolder.length() - 1);

        sql.append(") VALUES(");
        placeHolder.append(')');

        sql.append(placeHolder);

        return sql.toString() ;
    }

    public static String generateDeleteSQL(String tableName,String conditions){
        return join("delete from",tableName ,conditions);
    }

    private static String join(String ... params){
        int len =  0 ;

        for (String str : params){

            if(str == null || str.length() == 0)
                continue;

            len = len + 1 + str.length() ; //1 for ' '
        }
        char[] chars = new char[len];

        int pos = 0 ;
        for(String str : params){

            if(str == null || str.length() == 0)
                continue;
            int l = str.length();
            str.getChars(0, l, chars, pos);
            pos += l ;
            chars[pos++] = ' ';
        }

        return new String(chars);
    }

    public static void main(String args[]){

        System.out.println(join("select","age,sex","from","t1"));

        System.out.println(generateSelectSQL("","user","where id=?"));
        System.out.println(generateSelectSQL(null,"user","where id=?"));
        System.out.println(generateSelectSQL("id,name,age","user",""));
        System.out.println(generateSelectSQL("id,name,age", "user", null));
        System.out.println(generateDeleteSQL("user", null));
        System.out.println(generateDeleteSQL("user", "where id=?"));
        System.out.println(generateInsertSQL("user", "id", "name", "age"));

    }



}
